package org.admanager.acmeadmapping.plugin.diagram.providers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.admanager.acmeadmapping.plugin.diagram.edit.parts.CBAPatternCBAPatternCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ComponentComponentCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ComponentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ComponentMappingEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ComponentPortMappingEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ConnectorConnectorCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ConnectorEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ConnectorMappingEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.ConnectorRoleMappingEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.MappingRootEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponent2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponentPComponentCompartment2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponentPComponentCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponentPort2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PComponentPortEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnector2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnectorEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnectorPConnectorCompartment2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnectorPConnectorCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnectorRole2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PConnectorRoleEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PRoleEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.PortEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.RepresentationRepresentationCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.RoleEditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.SystemSystemCompartment2EditPart;
import org.admanager.acmeadmapping.plugin.diagram.edit.parts.SystemSystemCompartmentEditPart;
import org.admanager.acmeadmapping.plugin.diagram.part.AcmeADManagementMetamodelDiagramEditorPlugin;
import org.admanager.acmeadmapping.plugin.diagram.part.Messages;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.ui.services.modelingassistant.ModelingAssistantProvider;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

/**
 * @generated
 */
public class AcmeADManagementMetamodelModelingAssistantProvider extends
		ModelingAssistantProvider {

	/**
	 * @generated
	 */
	public List getTypesForPopupBar(IAdaptable host) {
		IGraphicalEditPart editPart = (IGraphicalEditPart) host
				.getAdapter(IGraphicalEditPart.class);
		if (editPart instanceof MappingRootEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					6);
			types.add(AcmeADManagementMetamodelElementTypes.ComponentPortMapping_2024);
			types.add(AcmeADManagementMetamodelElementTypes.ConnectorRoleMapping_2025);
			types.add(AcmeADManagementMetamodelElementTypes.ConnectorMapping_2026);
			types.add(AcmeADManagementMetamodelElementTypes.ComponentMapping_2027);
			types.add(AcmeADManagementMetamodelElementTypes.CBAPattern_2028);
			types.add(AcmeADManagementMetamodelElementTypes.System_2029);
			return types;
		}
		if (editPart instanceof PRoleEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					1);
			types.add(AcmeADManagementMetamodelElementTypes.PConstraint_3022);
			return types;
		}
		if (editPart instanceof CBAPatternCBAPatternCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					6);
			types.add(AcmeADManagementMetamodelElementTypes.PMultiplicity_3020);
			types.add(AcmeADManagementMetamodelElementTypes.PRole_3021);
			types.add(AcmeADManagementMetamodelElementTypes.PComponentPort_3023);
			types.add(AcmeADManagementMetamodelElementTypes.PConnectorRole_3024);
			types.add(AcmeADManagementMetamodelElementTypes.PComponent_3025);
			types.add(AcmeADManagementMetamodelElementTypes.PConnector_3030);
			return types;
		}
		if (editPart instanceof PComponentPComponentCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(AcmeADManagementMetamodelElementTypes.PComponent_3026);
			types.add(AcmeADManagementMetamodelElementTypes.PComponentPort_3027);
			types.add(AcmeADManagementMetamodelElementTypes.PConnector_3028);
			return types;
		}
		if (editPart instanceof PComponentPComponentCompartment2EditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(AcmeADManagementMetamodelElementTypes.PComponent_3026);
			types.add(AcmeADManagementMetamodelElementTypes.PComponentPort_3027);
			types.add(AcmeADManagementMetamodelElementTypes.PConnector_3028);
			return types;
		}
		if (editPart instanceof PConnectorPConnectorCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(AcmeADManagementMetamodelElementTypes.PConnector_3028);
			types.add(AcmeADManagementMetamodelElementTypes.PConnectorRole_3029);
			types.add(AcmeADManagementMetamodelElementTypes.PComponent_3026);
			return types;
		}
		if (editPart instanceof PConnectorPConnectorCompartment2EditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(AcmeADManagementMetamodelElementTypes.PConnector_3028);
			types.add(AcmeADManagementMetamodelElementTypes.PConnectorRole_3029);
			types.add(AcmeADManagementMetamodelElementTypes.PComponent_3026);
			return types;
		}
		if (editPart instanceof SystemSystemCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(AcmeADManagementMetamodelElementTypes.Component_3031);
			types.add(AcmeADManagementMetamodelElementTypes.Connector_3035);
			return types;
		}
		if (editPart instanceof ComponentComponentCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(AcmeADManagementMetamodelElementTypes.Port_3032);
			types.add(AcmeADManagementMetamodelElementTypes.Representation_3033);
			return types;
		}
		if (editPart instanceof RepresentationRepresentationCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					1);
			types.add(AcmeADManagementMetamodelElementTypes.System_3034);
			return types;
		}
		if (editPart instanceof SystemSystemCompartment2EditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(AcmeADManagementMetamodelElementTypes.Component_3031);
			types.add(AcmeADManagementMetamodelElementTypes.Connector_3035);
			return types;
		}
		if (editPart instanceof ConnectorConnectorCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(AcmeADManagementMetamodelElementTypes.Role_3036);
			types.add(AcmeADManagementMetamodelElementTypes.Representation_3033);
			return types;
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnSource(IAdaptable source) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentPortMappingEditPart) {
			return ((ComponentPortMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ConnectorRoleMappingEditPart) {
			return ((ConnectorRoleMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ConnectorMappingEditPart) {
			return ((ConnectorMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof PortEditPart) {
			return ((PortEditPart) sourceEditPart).getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof RoleEditPart) {
			return ((RoleEditPart) sourceEditPart).getMARelTypesOnSource();
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnTarget(IAdaptable target) {
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (targetEditPart instanceof PComponentPortEditPart) {
			return ((PComponentPortEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PConnectorRoleEditPart) {
			return ((PConnectorRoleEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentEditPart) {
			return ((PComponentEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponent2EditPart) {
			return ((PComponent2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentPort2EditPart) {
			return ((PComponentPort2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PConnectorEditPart) {
			return ((PConnectorEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PConnectorRole2EditPart) {
			return ((PConnectorRole2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PConnector2EditPart) {
			return ((PConnector2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ComponentEditPart) {
			return ((ComponentEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PortEditPart) {
			return ((PortEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ConnectorEditPart) {
			return ((ConnectorEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof RoleEditPart) {
			return ((RoleEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnSourceAndTarget(IAdaptable source,
			IAdaptable target) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentPortMappingEditPart) {
			return ((ComponentPortMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ConnectorRoleMappingEditPart) {
			return ((ConnectorRoleMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ConnectorMappingEditPart) {
			return ((ConnectorMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof PortEditPart) {
			return ((PortEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof RoleEditPart) {
			return ((RoleEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getTypesForSource(IAdaptable target,
			IElementType relationshipType) {
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (targetEditPart instanceof PComponentPortEditPart) {
			return ((PComponentPortEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PConnectorRoleEditPart) {
			return ((PConnectorRoleEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentEditPart) {
			return ((PComponentEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponent2EditPart) {
			return ((PComponent2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentPort2EditPart) {
			return ((PComponentPort2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PConnectorEditPart) {
			return ((PConnectorEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PConnectorRole2EditPart) {
			return ((PConnectorRole2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PConnector2EditPart) {
			return ((PConnector2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ComponentEditPart) {
			return ((ComponentEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PortEditPart) {
			return ((PortEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ConnectorEditPart) {
			return ((ConnectorEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof RoleEditPart) {
			return ((RoleEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getTypesForTarget(IAdaptable source,
			IElementType relationshipType) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentPortMappingEditPart) {
			return ((ComponentPortMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ConnectorRoleMappingEditPart) {
			return ((ConnectorRoleMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ConnectorMappingEditPart) {
			return ((ConnectorMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof PortEditPart) {
			return ((PortEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof RoleEditPart) {
			return ((RoleEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public EObject selectExistingElementForSource(IAdaptable target,
			IElementType relationshipType) {
		return selectExistingElement(target,
				getTypesForSource(target, relationshipType));
	}

	/**
	 * @generated
	 */
	public EObject selectExistingElementForTarget(IAdaptable source,
			IElementType relationshipType) {
		return selectExistingElement(source,
				getTypesForTarget(source, relationshipType));
	}

	/**
	 * @generated
	 */
	protected EObject selectExistingElement(IAdaptable host, Collection types) {
		if (types.isEmpty()) {
			return null;
		}
		IGraphicalEditPart editPart = (IGraphicalEditPart) host
				.getAdapter(IGraphicalEditPart.class);
		if (editPart == null) {
			return null;
		}
		Diagram diagram = (Diagram) editPart.getRoot().getContents().getModel();
		HashSet/*[org.eclipse.emf.ecore.EObject]*/elements = new HashSet/*[org.eclipse.emf.ecore.EObject]*/();
		for (Iterator/*[org.eclipse.emf.ecore.EObject]*/it = diagram
				.getElement().eAllContents(); it.hasNext();) {
			EObject element = (EObject) it.next();
			if (isApplicableElement(element, types)) {
				elements.add(element);
			}
		}
		if (elements.isEmpty()) {
			return null;
		}
		return selectElement((EObject[]) elements.toArray(new EObject[elements
				.size()]));
	}

	/**
	 * @generated
	 */
	protected boolean isApplicableElement(EObject element, Collection types) {
		IElementType type = ElementTypeRegistry.getInstance().getElementType(
				element);
		return types.contains(type);
	}

	/**
	 * @generated
	 */
	protected EObject selectElement(EObject[] elements) {
		Shell shell = Display.getCurrent().getActiveShell();
		ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
				AcmeADManagementMetamodelDiagramEditorPlugin.getInstance()
						.getItemProvidersAdapterFactory());
		ElementListSelectionDialog dialog = new ElementListSelectionDialog(
				shell, labelProvider);
		dialog.setMessage(Messages.AcmeADManagementMetamodelModelingAssistantProviderMessage);
		dialog.setTitle(Messages.AcmeADManagementMetamodelModelingAssistantProviderTitle);
		dialog.setMultipleSelection(false);
		dialog.setElements(elements);
		EObject selected = null;
		if (dialog.open() == Window.OK) {
			selected = (EObject) dialog.getFirstResult();
		}
		return selected;
	}
}
